/*****************************************************************************
 *
 * Weber State University
 * CS4280 Spring 2010
 * Group Assignment 5
 *
 *
 *   TTTTTT                               CCCCC
 *     TT   EEEEE   A    M   M          CC      C
 *     TT   E      A A   M   M         CC   
 *     TT   E     A   A  MM MM  -----  CC
 *     TT   EEE   AAAAA  M M M  -----  CC
 *     TT   E     A   A  M   M          CC      C
 *     TT   EEEEE A   A  M   M            CCCCC
 *
 *   Jared Pack ---- Jon Mann ---- Joshua Clayton
 *
 *
 * A flythrough of a simple textured 3D scene
 *
 ****************************************************************************/

 /* FILENAME scene.c
  *
  * Change control Section
  *
  * Team Member: Joshua Clayton
  * Version: 0.1
  * Date: 03/19/2010
  *     stopped the cube spinning (its nauseating)
  *     loaded three textures. Maybe we will use the other two somewhere
  *
  * Team Member: Joshua Clayton
  * Version: 0.2
  * Date: 03/22/2010
  *     Changed the files from C to C++ (Oops!)
  *     Made a generic fuction to draw a textured cube.
  *     Put the spinning cube back into the scene.
  * 	
  * 	
  * 	
  * Team Member: Jon Mann
  * Version: 0.3
  * Date: 03/23/2010
  *     Made minor changes to run in windows
  *     Made some minor changes in DrawGLScene() to enable camera controls
  *     
  */

#ifdef _WIN32
#include<windows.h> // needed for windows systems
#endif

#include <time.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>

#include <cstdlib>

#include "ImageLoad.h"

/* floats for x rotation, y rotation, z rotation */
extern float xrot, yrot, zrot;
GLuint texture[3];

static void drawTexuredCube(GLfloat size);

/* Load Bitmaps And Convert To Textures */
int LoadGLTexture(char * filename, GLuint *texture)
{ 
    struct Image *image1;
    
    image1 = (struct Image *) malloc(sizeof(struct Image));
    if (image1 == NULL)
    {
        return -1;
    }   
    
    if (!ImageLoad(filename, image1))
    {
        return -1;
    }        
    
    glGenTextures(1, texture);
    /* 2d texture (x and y size) */
    glBindTexture(GL_TEXTURE_2D, *texture);
    /* scale linearly when image bigger than texture */
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    /* scale linearly when image smalled than texture */
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    
    /* 2d texture, level of detail 0 (normal),
     * 3 components (red, green, blue), x size from image,
     * y size from image, border 0 (normal),
     * rgb color data, unsigned byte data, and finally the data itself. */
    glTexImage2D(GL_TEXTURE_2D, 0, 3, image1->sizeX, image1->sizeY,
                 0, GL_RGB, GL_UNSIGNED_BYTE, image1->data);
    return 0;             
};               

void DrawGLScene()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    //glLoadIdentity();

    //glTranslatef(0.0f,0.0f,-5.0f);
    glPushMatrix();
    
    //glRotatef(xrot,1.0f,0.0f,0.0f);
    glRotatef(yrot,0.0f,1.0f,0.0f);
    glRotatef(zrot,0.0f,0.0f,1.0f);

    glBindTexture(GL_TEXTURE_2D, texture[1]);   // choose the texture to use.
    drawTexuredCube(2);

    glPopMatrix();
    glBindTexture(GL_TEXTURE_2D, texture[0]);   // choose the texture to use.
    drawTexuredCube(-20.0);



    // since this is double buffered, swap the buffers to display what just got drawn.
    glutSwapBuffers();
}

void rotateCube(void)
{
    static clock_t base_clock = 0;
    clock_t current_clock = clock();

    /* rotate 180 degrees per second */
    float rot_degrees = (float)(current_clock - base_clock) * 180 / CLOCKS_PER_SEC;
    
    /* It looks better rotating only on two of three axes */
    //    xrot+=rot_degrees;                        // X Axis Rotation    
    yrot+=rot_degrees;                        // Y Axis Rotation
    zrot+=rot_degrees;                        // Z Axis Rotation

    base_clock = current_clock;                 //Update the base time

    /* tell glut to redraw the scene at its earliest convenience */
    glutPostRedisplay();
}


/* negative size yields an inside-out cube (e.g. textured on the inside */
static void drawTexuredCube(GLfloat size)
{
    size /= 2;

    glBegin(GL_QUADS);                        // begin drawing a cube
    
    // Front Face (note that the texture's corners have to match the quad's corners)
    glTexCoord2f(0.0f, 0.0f);
    glVertex3f(-size, -size,  size);    // Bottom Left Of The Texture and Quad
    glTexCoord2f(1.0f, 0.0f);
    glVertex3f( size, -size,  size);    // Bottom Right Of The Texture and Quad
    glTexCoord2f(1.0f, 1.0f);
    glVertex3f( size,  size,  size);    // Top Right Of The Texture and Quad
    glTexCoord2f(0.0f, 1.0f);
    glVertex3f(-size,  size,  size);    // Top Left Of The Texture and Quad
    
    // Back Face
    glTexCoord2f(1.0f, 0.0f);
    glVertex3f(-size, -size, -size);    // Bottom Right Of The Texture and Quad
    glTexCoord2f(1.0f, 1.0f);
    glVertex3f(-size,  size, -size);    // Top Right Of The Texture and Quad
    glTexCoord2f(0.0f, 1.0f);
    glVertex3f( size,  size, -size);    // Top Left Of The Texture and Quad
    glTexCoord2f(0.0f, 0.0f);
    glVertex3f( size, -size, -size);    // Bottom Left Of The Texture and Quad
    
    // Top Face
    glTexCoord2f(0.0f, 1.0f);
    glVertex3f(-size,  size, -size);    // Top Left Of The Texture and Quad
    glTexCoord2f(0.0f, 0.0f);
    glVertex3f(-size,  size,  size);    // Bottom Left Of The Texture and Quad
    glTexCoord2f(1.0f, 0.0f);
    glVertex3f( size,  size,  size);    // Bottom Right Of The Texture and Quad
    glTexCoord2f(1.0f, 1.0f);
    glVertex3f( size,  size, -size);    // Top Right Of The Texture and Quad
    
    // Bottom Face       
    glTexCoord2f(1.0f, 1.0f);
    glVertex3f(-size, -size, -size);    // Top Right Of The Texture and Quad
    glTexCoord2f(0.0f, 1.0f);
    glVertex3f( size, -size, -size);    // Top Left Of The Texture and Quad
    glTexCoord2f(0.0f, 0.0f);
    glVertex3f( size, -size,  size);    // Bottom Left Of The Texture and Quad
    glTexCoord2f(1.0f, 0.0f);
    glVertex3f(-size, -size,  size);    // Bottom Right Of The Texture and Quad
    
    // Right face
    glTexCoord2f(1.0f, 0.0f);
    glVertex3f( size, -size, -size);    // Bottom Right Of The Texture and Quad
    glTexCoord2f(1.0f, 1.0f);
    glVertex3f( size,  size, -size);    // Top Right Of The Texture and Quad
    glTexCoord2f(0.0f, 1.0f);
    glVertex3f( size,  size,  size);    // Top Left Of The Texture and Quad
    glTexCoord2f(0.0f, 0.0f);
    glVertex3f( size, -size,  size);    // Bottom Left Of The Texture and Quad
    
    // Left Face
    glTexCoord2f(0.0f, 0.0f);
    glVertex3f(-size, -size, -size);    // Bottom Left Of The Texture and Quad
    glTexCoord2f(1.0f, 0.0f);
    glVertex3f(-size, -size,  size);    // Bottom Right Of The Texture and Quad
    glTexCoord2f(1.0f, 1.0f);
    glVertex3f(-size,  size,  size);    // Top Right Of The Texture and Quad
    glTexCoord2f(0.0f, 1.0f);
    glVertex3f(-size,  size, -size);    // Top Left Of The Texture and Quad
    
    glEnd();                                    // done with the polygon.
}
